#include "QVideoManager.h"
#include "QEnrolDialog.h"
#include "QAddCategoryDialog.h"
#include <QCryptographicHash>



QVideoManager::QVideoManager(QWidget *parent)
    : QMainWindow(parent)
{

    mLog = new QTextEdit();
    mLog->setGeometry(1200,100,400,720);
    mLog->show();


    init();

    initWidget();

    readSettings();

    checkStoreDirPath();

    getAllFileInfo(mStoreDirPath);

    initConnect();

    mLog->append(QString("total video : %1 count ").arg(mFileInfoHash->count(),0,10));

    openDB();

    createTable();

    // connectCategoryModel();
    // connectVideoModel();
    compareData();
    createCategoryArea();


}

QVideoManager::~QVideoManager()
{
    
}

void QVideoManager::initWidget(){

    mMainWidget = new QWidget(this);
    mMainWidget->setGeometry(0,0,1080,720);

    mStoreDirOpenButton = new QPushButton(mMainWidget);
    mStoreDirOpenButton->setGeometry(10,10,80,80);
    mStoreDirOpenButton->setText("OepnDir");

    mManagerAndTorrentToggleButton = new QPushButton(mMainWidget);
    mManagerAndTorrentToggleButton->setGeometry(100,10,80,80);
    mManagerAndTorrentToggleButton->setText("Torrent");

    mCategoryAddButton = new QPushButton(mMainWidget);
    mCategoryAddButton->setGeometry(190,10,80,80);
    mCategoryAddButton->setText("AddCategory");

    mSearchLineEdit = new QLineEdit(mMainWidget);
    mSearchLineEdit->setGeometry(890,70,120,20);

    mSearchButton = new QPushButton(mMainWidget);
    mSearchButton->setGeometry(1020,70,50,20);
    mSearchButton->setText("Search");

    mCategoryWidget = new QWidget(mMainWidget);
    mCategoryWidget->setGeometry(10,100,200,610);
    //    mCategoryTreeView = new QTreeView(mMainWidget);
    //    mCategoryTreeView->setGeometry(10,100,200,610);


    mVideoTableWidget = new QTableWidget(mMainWidget);
    mVideoTableWidget->setGeometry(220,100,850,610);
    mVideoTableWidget->setColumnCount(4);



    QTableWidgetItem *item0 = new QTableWidgetItem();
    item0->setText("FileName");
    mVideoTableWidget->setHorizontalHeaderItem(0, item0);
    mVideoTableWidget->setColumnWidth(0, 200);

    QTableWidgetItem *item1 = new QTableWidgetItem();
    item1->setText("FileSize");
    mVideoTableWidget->setHorizontalHeaderItem(1, item1);
    mVideoTableWidget->setColumnWidth(1, 100);

    QTableWidgetItem *item2 = new QTableWidgetItem();
    item2->setText("FilePath");
    mVideoTableWidget->setHorizontalHeaderItem(2, item2);
    mVideoTableWidget->setColumnWidth(2, 433);

    QTableWidgetItem *item3 = new QTableWidgetItem();
    item3->setText("Save");
    mVideoTableWidget->setHorizontalHeaderItem(3, item3);
    mVideoTableWidget->setColumnWidth(3, 100);

    mVideoTableView = new QTableView(mMainWidget);
    mVideoTableView->setGeometry(220,100,850,610);
    mVideoTableView->setVisible(false);

    mLog->append("initLayout success \n");

}

void QVideoManager::readSettings(){

    // QSettings setting("PlayGround","QVideoManager");
    //setStoreDirPath(setting.value("StoreDirPath").toString());

    QFile file("info.xml");
    file.open(QFile::ReadWrite|QFile::Text);

    QXmlStreamReader stream(&file);
    stream.readNextStartElement();
    setStoreDirPath(stream.readElementText());

    mLog->append("readPath : "+stream.readElementText()+"\n");


    file.close();


}

void QVideoManager::writeSettings(){

    //    QSettings setting("PlayGround","QVideoManager");

    //    setting.setValue("StoreDirPath",getStoreDirPath());


    //    mLog->append("writeSettings : "+mStoreDirPath+"\n");

    QFile file("info.xml");
    file.open(QFile::ReadWrite|QFile::Text);

    QXmlStreamWriter stream(&file);
    stream.setAutoFormatting(true);
    stream.writeStartDocument();
    stream.writeTextElement("StoreDirPath",getStoreDirPath());
    stream.writeEndElement();
    stream.writeEndDocument();

    file.close();

}

QString QVideoManager::getStoreDirPath(){

    return mStoreDirPath;
}

void QVideoManager::setStoreDirPath(QString str){
    mStoreDirPath = str;
}

void QVideoManager::checkStoreDirPath(){
    if(mStoreDirPath == NULL){
        int requestNumber = QMessageBox::warning(mMainWidget,"empty store-dir path","store-dir path must be enroled.\n Do you want to enrol, right now?",QMessageBox::Yes | QMessageBox::No);
        if(requestNumber == QMessageBox::Yes){
            mStoreDirPath = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
                                                              "c:\\",
                                                              NULL);
            mLog->append("FileDialog  : "+mStoreDirPath);
            writeSettings();
        }else if(requestNumber == QMessageBox::No){
            return;
        }
    }

}

void QVideoManager::setStoreDirPathSlot(){
    mStoreDirPath = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
                                                      "c:\\",
                                                      NULL);
    mLog->append("FileDialog  : "+mStoreDirPath);

    writeSettings();


    if(mFileInfoHash != NULL){
        delete mFileInfoHash;
    }

    mFileInfoHash = new QHash<QString,QFileInfo*>();

    getAllFileInfo(mStoreDirPath);

    mLog->append(QString("total video : %1 count \n ").arg(mFileInfoHash->count(),0,10));


}

void QVideoManager::getAllFileInfo(const QString &path){

    QDir dir(path);


    foreach(QString file, dir.entryList(mFilters,QDir::Files)){
        QFileInfo *info = new QFileInfo(dir,file);
        QCryptographicHash cypt(QCryptographicHash::Md5);
        QFile mdfile(info->absoluteFilePath());
        if(!mdfile.open(QIODevice::ReadOnly)){
            return;
        }
        cypt.addData(mdfile.readAll());
        mdfile.close();
        QString result = cypt.result();
        mLog->append("hash : "+result+"\n");
        mFileInfoHash->insert(result,info);
        mLog->append(info->fileName()+"\n");
    }

    foreach(QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)){
        getAllFileInfo(path + QDir::separator() + subDir);
    }


}

void QVideoManager::init(){

    this->setGeometry(100,100,1080,720);



    mFileInfoHash = new QHash<QString,QFileInfo*>();

    mEnrolMap = new QMap<int,QString>();

    mEnrolButtonGroup = new QButtonGroup(this);
    mCategoryButtonGroup = new QButtonGroup(this);

    mCategoryButtonIndex = 0;



    mFilters += "*.avi";
    mFilters += "*.mp4";
    mFilters += "*.wmv";
    mFilters += "*.mkv";
    mFilters += "*.flv";
    mFilters += "*.swf";
    mFilters += "*.rmvb";
    mFilters += "*.k3g";
    mFilters += "*.mov";
    mFilters += "*.skm";

    mLog->append("init success \n");

}

void QVideoManager::initConnect(){

    connect(mStoreDirOpenButton,SIGNAL(clicked()),this,SLOT(setStoreDirPathSlot()));
    connect(mCategoryAddButton,SIGNAL(clicked()),this,SLOT(addCategorySlot()));
    connect(mSearchButton,SIGNAL(clicked()),this,SLOT(searchVideoSlot()));
    mLog->append("initConnect success \n");

}

void QVideoManager::openDB(){
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("qvideomanager.db");
    if (!db.open()) {
        QMessageBox::critical(0, tr("Cannot open database"),
                              tr("Unable to establish a database connection.\n"
                                 "This example needs SQLite support. Please read "
                                 "the Qt SQL driver documentation for information how "
                                 "to build it."), QMessageBox::Cancel);
        return;
    }

    mLog->append("openDB success \n");
}

void QVideoManager::createTable(){
    QSqlQuery query;
    query.exec("create table video (key text, size integer, name text, category integer,contents text,tag0 text,tag1 text,tag2 text,tag3 text,tag4 text,score integer)");
    mLog->append("Create Table : video \n");


    query.exec("create table category (id integer primary key, name text)");
    mLog->append("Create Table : category \n");

}



void QVideoManager::compareData(){

    int i = 0;
    QSqlQuery query;
    query.exec("select key from video");



    while(query.next()){
        QString key = query.value(0).toString();
        if(mFileInfoHash->contains(key)){
            mFileInfoHash->remove(key);
            mLog->append("Hash delete \n");
        }
    }


    QHashIterator<QString,QFileInfo*> itr(*mFileInfoHash);

    mVideoTableWidget->setRowCount(mFileInfoHash->count());

    while(itr.hasNext()){
        itr.next();
        QFileInfo* info = (QFileInfo*) itr.value();
        QString key = (QString)itr.key();

        QTableWidgetItem *itemName = new QTableWidgetItem();
        itemName->setText(info->fileName());
        mVideoTableWidget->setItem(i,0,itemName);

        QTableWidgetItem *itemSize = new QTableWidgetItem();
        itemSize->setText(QString("%1").arg(info->size(),0,10));
        mVideoTableWidget->setItem(i,1,itemSize);

        QTableWidgetItem *itemPath = new QTableWidgetItem();
        itemPath->setText(info->absolutePath());
        mVideoTableWidget->setItem(i,2,itemPath);

        QPushButton *button = new QPushButton("Enrol");
        mEnrolButtonGroup->addButton(button,i);
        mVideoTableWidget->setCellWidget(i,3,button);

        mEnrolMap->insert(i,key);

        i++;

    }
    connect(mEnrolButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(enrolVideoInfomationSlot(int)));


}

void QVideoManager::enrolVideoInfomationSlot(int id){

    mEnrolTempIndex = id;
    QString key = (QString) mEnrolMap->value(id);
    QFileInfo* file = (QFileInfo*) mFileInfoHash->value(key);
    QEnrolDialog *enrolDialog = new QEnrolDialog();
    enrolDialog->setFileInfo(key,file);
    enrolDialog->exec();

    connect(enrolDialog,SIGNAL(destroyed()),this,SLOT(notdefineRefreshSlot()));


}

void QVideoManager::createCategoryArea(){

    QPushButton *notDefine = new QPushButton(mCategoryWidget);
    notDefine->setGeometry(10,10,180,50);
    notDefine->setText("Not Define");

    connect(notDefine,SIGNAL(clicked()),this,SLOT(showNotDefineSlot()));

    QSqlQuery query;
    query.exec("select id,name from category");


    while(query.next()){
        int categoryID = query.value(0).toInt();
        QString categoryName = query.value(1).toString();

        QPushButton *categoryButton = new QPushButton(mCategoryWidget);
        categoryButton->setGeometry(10,65+(mCategoryButtonIndex*55),180,50);
        categoryButton->setText(categoryName);
        mCategoryButtonGroup->addButton(categoryButton,categoryID);

        mCategoryButtonIndex++;

    }

    connect(mCategoryButtonGroup,SIGNAL(buttonClicked(int)),this,SLOT(showSelectedCategorySlot(int)));


}

void QVideoManager::addCategorySlot(){
    QAddCategoryDialog *dialog = new QAddCategoryDialog();
    int result = dialog->exec();
    if(result == 1){
        QSqlQuery query;
        query.exec("select id,name from category");
        query.last();
        int categoryID = query.value(0).toInt();
        QString categoryName = query.value(1).toString();

        QPushButton *categoryButton = new QPushButton(mCategoryWidget);
        categoryButton->setGeometry(10,65+(mCategoryButtonIndex*55),180,50);
        categoryButton->setText(categoryName);
        categoryButton->show();
        mCategoryButtonGroup->addButton(categoryButton,categoryID);

        mCategoryButtonIndex++;

    }

}



void QVideoManager::showSelectedCategorySlot(int i){

    mVideoTableWidget->setVisible(false);

    //    if(mSQLvideoTableModel != NULL){
    //        delete mSQLvideoTableModel;
    //    }


    mSQLvideoTableModel = new QSqlTableModel(this);
    mSQLvideoTableModel->setTable("video");
    mSQLvideoTableModel->setFilter(QString("category = %1").arg(i,0,10));
    mSQLvideoTableModel->select();

    mVideoTableView->setModel(mSQLvideoTableModel);
    mVideoTableView->setColumnHidden(0,true);
    mVideoTableView->setColumnHidden(1,true);
    mVideoTableView->setColumnWidth(2,200);
    mVideoTableView->setColumnHidden(3,true);
    mVideoTableView->setColumnWidth(4,583);
    mVideoTableView->setColumnHidden(5,true);
    mVideoTableView->setColumnHidden(6,true);
    mVideoTableView->setColumnHidden(7,true);
    mVideoTableView->setColumnHidden(8,true);
    mVideoTableView->setColumnHidden(9,true);
    mVideoTableView->setColumnWidth(10,50);
    mVideoTableView->setVisible(true);

}

void QVideoManager::showNotDefineSlot(){
    mVideoTableView->setVisible(false);
    mVideoTableWidget->setVisible(true);

}


void QVideoManager::searchVideoSlot(){

    QString keyword = mSearchLineEdit->text();


    mVideoTableWidget->setVisible(false);

    mSQLvideoTableModel = new QSqlTableModel(this);
    mSQLvideoTableModel->setTable("video");
    mSQLvideoTableModel->setFilter("name='"+keyword+"' or tag0='"+keyword+"' or tag1='"+keyword+"' or tag2='"+keyword+"' or tag3='"+keyword+"' or tag4='"+keyword+"'");
    mSQLvideoTableModel->select();

    mVideoTableView->setModel(mSQLvideoTableModel);
    mVideoTableView->setColumnHidden(0,true);
    mVideoTableView->setColumnHidden(1,true);
    mVideoTableView->setColumnWidth(2,200);
    mVideoTableView->setColumnHidden(3,true);
    mVideoTableView->setColumnWidth(4,583);
    mVideoTableView->setColumnHidden(5,true);
    mVideoTableView->setColumnHidden(6,true);
    mVideoTableView->setColumnHidden(7,true);
    mVideoTableView->setColumnHidden(8,true);
    mVideoTableView->setColumnHidden(9,true);
    mVideoTableView->setColumnWidth(10,50);
    mVideoTableView->setVisible(true);

}

void QVideoManager::notdefineRefreshSlot(){
    QString key = (QString) mEnrolMap->value(mEnrolTempIndex);
    QSqlQuery query;
    query.exec("select * from video where key = '"+key+"'");
    if(query.next()){
        mFileInfoHash->remove(key);
        mEnrolMap->remove(mEnrolTempIndex);
        mVideoTableWidget->removeRow(mEnrolTempIndex);

    }


}
